package com.example.aigc_education.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.domain.Answer;
import com.example.aigc_education.domain.po.SelectAnswerByAdminPO;
import com.example.aigc_education.domain.po.SelectAnswerByQuestionPO;
import com.example.aigc_education.domain.po.SelectAnswerByUserPO;
import com.example.aigc_education.mapper.AnswerMapper;
import com.example.aigc_education.service.AnswerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
public class AnswerServiceImpl extends ServiceImpl<AnswerMapper, Answer> implements AnswerService {
    @Resource
    private AnswerMapper answerMapper;
    /**
     * 添加答案。
     *
     * 本方法通过调用answerMapper的insert方法来尝试添加一个新的答案记录到数据库。
     * 如果添加过程中出现异常，方法将捕获该异常并抛出一个运行时异常，指示答案添加失败。
     * 使用@Transactional注解确保方法操作的数据库事务性，即如果操作失败能够回滚。
     *
     * @param answer 待添加的答案对象，包含答案的详细信息。
     * @throws BusinessException 如果答案添加过程中发生异常，则抛出此运行时异常。
     */
    @Override
    @Transactional
    public void addAnswer(Answer answer) {
        try {
            answerMapper.insert(answer);
        } catch (Exception e) {
            throw new BusinessException("添加答案失败");
        }
    }

    /**
     * 更新答案信息。
     *
     * 本方法通过提供一个新的答案对象和答案ID，来更新数据库中对应答案的记录。
     * 使用了事务@Transactional确保操作的原子性。
     * 如果更新过程中发生异常，方法将抛出一个运行时异常，指示答案更新失败。
     *
     * @param answer 新的答案对象，包含需要更新的信息。
     * @param answerId 需要更新的答案的ID，用于定位特定的答案记录。
     * @throws BusinessException 如果更新答案的过程中发生异常，将抛出此运行时异常。
     */
    @Override
    @Transactional
    public void updateAnswer(Answer answer, Long answerId) {
        try {
            // 创建UpdateWrapper用于构建更新条件，这里指定根据answerId进行更新。
            UpdateWrapper<Answer> wrapper = new UpdateWrapper<>();
            wrapper.eq("answer_id", answerId);
            // 调用answerMapper的update方法，传入新的答案对象和更新条件，执行更新操作。
            answerMapper.update(answer, wrapper);
        } catch (Exception e) {
            // 如果更新过程中发生异常，抛出运行时异常，并提示更新答案失败。
            throw new BusinessException("更新答案失败");
        }
    }

    /**
     * 删除答案。
     *
     * 使用事务确保操作的原子性，如果操作失败，整个事务将被回滚。
     * 此方法通过查询答案ID来定位答案，并将其从数据库中删除。
     *
     * @param answerId 答案的唯一标识符。
     * @throws BusinessException 如果删除过程中发生异常，则抛出运行时异常。
     */
    @Override
    @Transactional
    public void deleteAnswer(Long answerId) {
        try {
            // 创建UpdateWrapper用于构建删除条件。
            // 创建UpdateWrapper用于构建更新条件，这里指定根据answerId进行更新。
            UpdateWrapper<Answer> wrapper = new UpdateWrapper<>();
            // 设置删除条件为答案ID等于传入的answerId。
            wrapper.eq("answer_id", answerId);
            // 调用answerMapper的delete方法，使用构建的条件删除答案。
            // 调用answerMapper的update方法，传入新的答案对象和更新条件，执行更新操作。
            answerMapper.delete(wrapper);
        } catch (Exception e) {
            // 如果删除过程中发生异常，抛出运行时异常，并提供错误信息。
            // 如果更新过程中发生异常，抛出运行时异常，并提示更新答案失败。
            throw new BusinessException("删除答案失败");
        }
    }


    /**
     * 根据用户ID和考试ID查询用户的答题详情。
     *
     * 此方法通过调用answerMapper的selectAnswerAndQuestionByUser方法，获取指定用户在指定考试中的答题详情。
     * 如果查询过程中发生异常，方法将捕获异常并抛出一个运行时异常，提示查询失败。
     * 使用@Transactional注解确保该方法的数据库操作具备事务性。
     *
     * @param userId 用户ID，用于指定查询哪个用户的答题详情。
     * @param examId 考试ID，用于指定查询哪个考试的答题详情。
     * @return 返回一个List，包含用户的答题详情，每个详情包括答案和对应的题目。
     * @throws BusinessException 如果查询过程中发生异常，抛出运行时异常并提示查询失败。
     */
    @Override
    public List<SelectAnswerByUserPO> selectAnswerAndQuestionByUser(Long userId, Long examId) {
        try {
            // 调用answerMapper的selectAnswerAndQuestionByUser方法，传入用户ID和考试ID，查询用户的答案和问题信息。
            return answerMapper.selectAnswerAndQuestionByUser(userId, examId);
        } catch (Exception e) {
            // 如果查询过程中发生异常，抛出运行时异常，并提示查询失败。
            throw new BusinessException("查询答卷详细内容失败");
        }
    }

    /**
     * 根据题目ID和考试ID查询参加本场考试的所有学生该题作答情况。
     * 此方法用于教师查看特定题目在特定考试中的单题作答情况。
     *
     * @param questionId 题目ID，用于指定查询的题目。
     * @param examId 考试ID，用于指定查询的考试。
     * @return 返回一个包含作答情况的列表，每个元素代表一个学生的作答情况。
     * @throws BusinessException 如果查询过程中出现异常，则抛出运行时异常，并附带错误信息。
     */
    @Override
    public List<SelectAnswerByQuestionPO> selectSingleAnswerStation(Long questionId, Long examId) {
        try {
            // 调用answerMapper的selectAnswerByTeacher方法查询作答情况
            return answerMapper.selectAnswerByTeacher(questionId, examId);
        } catch (Exception e) {
            // 捕获异常，抛出运行时异常并附带错误信息
            throw new BusinessException("查询该题单题作答情况失败");
        }
    }


    /**
     * 通过管理员身份查询所有答案
     *
     * @return List<SelectAnswerByAdminPO> 返回所有答案的列表，每个答案包含详细信息。
     * @throws BusinessException 如果查询过程中发生异常，则抛出运行时异常，并给出具体错误信息。
     */
    @Override
    public List<SelectAnswerByAdminPO> selectAllAnswer() {
        try {
            // 尝试调用answerMapper的selectAllAnswer方法来查询所有答案。
            return answerMapper.selectAllAnswer();
        } catch (Exception e) {
            // 如果查询过程中出现异常，抛出运行时异常并附带错误信息。
            throw new BusinessException("查询所有答案失败");
        }
    }












}
